import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'dart:typed_data';

import 'package:device_info/device_info.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:package_info/package_info.dart';
import 'package:path/path.dart';
import 'package:path_provider/path_provider.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:sqflite/sqflite.dart';

import '../beans/sql.dart';
import '../exception/exception.dart';
import '../impl/impl.dart';

class ConnectUtil {
  static String getIpAdd(String ipAdd) {
    String address;
    if (TextUtils.isEmpty(ipAdd)) {
      address = ServerImpl.DEFAULT_IPADD;
      return address;
    }
    try {
      if (ipAdd.contains(':')) {
        address = ipAdd;
      } else {
        address = ipAdd + ":" + ServerImpl.DEFAULT_PORT;
      }
    } catch (e) {
      address = ServerImpl.DEFAULT_IPADD;
    }
    return address;
  }

  static String getError(Object error) {
    if (null == error) {
      return "未知异常";
    }
    if (error is CancelException || error is ExecuteException) {
      return error.toString();
    } else if (error is SocketException) {
      //return error.osError.message;
      return error.message;
    } else if (error is TimeoutException) {
      return '连接服务器超时';
    } else
      return error.toString();
  }
}

//
class PlatformKit {
  static const platform = const MethodChannel("com.flutter.scrap");

  /*return String and no params*/
  /*static Future<String> get(MethodChannel platform, String method) async {
    try {
      final String result = await platform.invokeMethod(method);
      return result;
    } on PlatformException {
      return "";
    }
  }*/
  /*return String and has params*/
  static Future<String> get(String method, [dynamic arguments]) async {
    try {
      final String result = await platform.invokeMethod(method, arguments);
      return result;
    } on PlatformException {
      return "";
    }
  }

  static Future<Null> getWithNoResult(String method,
      [dynamic arguments]) async {
    try {
      await platform.invokeMethod(method, arguments);
    } on PlatformException {}
  }

  static void showPackage() {
    PackageInfo.fromPlatform().then((value) {
      //APP名称
      String appName = value.appName;
      Log.out('$appName');

      //包名
      String packageName = value.packageName;
      Log.out('$packageName');

      //版本名
      String version = value.version;
      Log.out('$version');
      //版本号
      String buildNumber = value.buildNumber;
      Log.out('$buildNumber');
    });
  }

  static Future<PackageInfo> package() async {
    /*//APP名称
    packageMap.putIfAbsent('appName', () => value.appName);

    //包名
    packageMap.putIfAbsent('packageName', () => value.packageName);

    //版本名
    packageMap.putIfAbsent('version', () => value.version);
    //版本号
    packageMap.putIfAbsent('buildNumber', () => value.buildNumber);*/
    return await PackageInfo.fromPlatform();
  }

  static Future<Map<String, String>> device() async {
    DeviceInfoPlugin deviceInfoPlugin = DeviceInfoPlugin();
    Map<String, String> deviceMap = {};
    if (Platform.isAndroid) {
      AndroidDeviceInfo androidValue = await deviceInfoPlugin.androidInfo;
      String serial = await get('deviceSerial');

      deviceMap.putIfAbsent('deviceModel', () => androidValue.model);
      deviceMap.putIfAbsent('deviceName', () => androidValue.manufacturer);
      //deviceMap.putIfAbsent('deviceSerial', () => androidValue.device);
      deviceMap.putIfAbsent('deviceSerial', () => serial);
      return deviceMap;
    } else if (Platform.isIOS) {
      IosDeviceInfo iosValue = await deviceInfoPlugin.iosInfo;
      deviceMap.putIfAbsent('deviceModel', () => iosValue.name);
      deviceMap.putIfAbsent('deviceName', () => iosValue.localizedModel);

      String identifierVendor = iosValue.identifierForVendor;
      String temp = identifierVendor.replaceAll("-", "");

      StringBuffer buffer = StringBuffer("IOS");
      List<String> sss = temp.split('');
      while (buffer.length < 17) {
        try {
          int index = (sss.length % buffer.length);
          int item = 2 == index ? sss.length - buffer.length : index;
          buffer.write(sss[item]);
        } catch (e) {
          buffer.write(sss[buffer.length]);
        }
      }

      deviceMap.putIfAbsent('deviceSerial', () => buffer.toString());
      //{name: iPhone XR, systemName: iOS, systemVersion: 12.1, model: iPhone, localizedModel: iPhone, identifierForVendor: 7EF0BF1D-9786-4B78-9F3F-75D65983FB17, isPhysicalDevice: false, utsname.sysname:: Darwin, utsname.nodename:: promote.cache-dns.local, utsname.release:: 17.7.0, utsname.version:: Darwin Kernel Version 17.7.0: Wed Apr 24 21:17:24 PDT 2019; root:xnu-4570.71.45~1/RELEASE_X86_64, utsname.machine:: x86_64}
      return deviceMap;
    }
    return deviceMap;
  }

  static void showDevice() {
    DeviceInfoPlugin deviceInfoPlugin = DeviceInfoPlugin();
    if (Platform.isAndroid) {
      deviceInfoPlugin.androidInfo.then((androidValue) {
        Log.out('${_readAndroid(androidValue).toString()}');
      });
    } else if (Platform.isIOS) {
      deviceInfoPlugin.iosInfo.then((iosValue) {
        //flutter: {name: iPhone XR, systemName: iOS, systemVersion: 12.1, model: iPhone, localizedModel: iPhone, identifierForVendor: 7EF0BF1D-9786-4B78-9F3F-75D65983FB17, isPhysicalDevice: false, utsname.sysname:: Darwin, utsname.nodename:: promote.cache-dns.local, utsname.release:: 17.7.0, utsname.version:: Darwin Kernel Version 17.7.0: Wed Apr 24 21:17:24 PDT 2019; root:xnu-4570.71.45~1/RELEASE_X86_64, utsname.machine:: x86_64}
        Log.out('${_readIos(iosValue).toString()}');
      });
    }
  }

  static Map<String, dynamic> _readAndroid(AndroidDeviceInfo android) {
    return <String, dynamic>{
      'version.securityPatch': android.version.securityPatch,
      'version.sdkInt': android.version.sdkInt,
      'version.release': android.version.release,
      'version.previewSdkInt': android.version.previewSdkInt,
      'version.incremental': android.version.incremental,
      'version.codename': android.version.codename,
      'version.baseOS': android.version.baseOS,
      'board': android.board,
      'bootloader': android.bootloader,
      'brand': android.brand,
      'device': android.device,
      'display': android.display,
      'fingerprint': android.fingerprint,
      'hardware': android.hardware,
      'host': android.host,
      'id': android.id,
      'manufacturer': android.manufacturer,
      'model': android.model,
      'product': android.product,
      'supported32BitAbis': android.supported32BitAbis,
      'supported64BitAbis': android.supported64BitAbis,
      'supportedAbis': android.supportedAbis,
      'tags': android.tags,
      'type': android.type,
      'isPhysicalDevice': android.isPhysicalDevice,
      'androidId': android.androidId
    };
  }

  static Map<String, dynamic> _readIos(IosDeviceInfo ios) {
    return <String, dynamic>{
      'name': ios.name,
      'systemName': ios.systemName,
      'systemVersion': ios.systemVersion,
      'model': ios.model,
      'localizedModel': ios.localizedModel,
      'identifierForVendor': ios.identifierForVendor,
      'isPhysicalDevice': ios.isPhysicalDevice,
      'utsname.sysname:': ios.utsname.sysname,
      'utsname.nodename:': ios.utsname.nodename,
      'utsname.release:': ios.utsname.release,
      'utsname.version:': ios.utsname.version,
      'utsname.machine:': ios.utsname.machine,
    };
  }
}

class TextUtils {
  static bool isEmpty(String str) {
    return null == str || str.trim().isEmpty;
  }

  static bool nullable(String str) {
    return equals('null', str) || ObjUtils.nullable(str);
  }

  static String replaceNull(String str) {
    if (isEmpty(str) || nullable(str))
      return '';
    else
      return str;
  }

  static String replace(Object str, String defaultObj) {
    if (nullable(str))
      return defaultObj;
    else
      return str;
  }

  static bool equals(String a, String b) {
    return a == b;
  }

  static bool endWith(String a, String b) {
    if (nullable(a)) {
      return false;
    }
    return a.endsWith(b);
  }
}

class ObjUtils {
  static bool nullable(Object obj) {
    return null == obj;
  }

  static bool notNull(Object obj) {
    return null != obj;
  }
}

class ToastUtil {
  static var _entry;
  static var _timer;

  static void show(BuildContext context, String text) {
    if (null != _timer && _timer.isActive) {
      _timer.cancel();
      _timer = null;
      _entry?.remove();
      _entry = null;
    }
    const style = TextStyle(
        decoration: TextDecoration.none, color: Colors.white, fontSize: 15.0);
    var _widget = Column(
      children: <Widget>[
        Expanded(child: Container()),
        Container(
          decoration: BoxDecoration(
              color: Colors.black45,
              borderRadius: BorderRadius.all(Radius.circular(20.0))),
          padding: EdgeInsets.symmetric(vertical: 5.0, horizontal: 10.0),
          margin:
              EdgeInsets.only(bottom: MediaQuery.of(context).size.height / 8),
          child: Text(text, style: style),
        )
      ],
    );
    if (null == _entry) {
      _entry = OverlayEntry(
        builder: (_) => _widget,
      );
      Overlay.of(context).insert(_entry);
    }
    _timer = Timer(Duration(seconds: 2), () {
      if (null != _entry) {
        _entry?.remove();
        _entry = null;
      }
    });
  }
}

class PermissionUtil {
  static void request(
      List<Permission> permissions, PermissionImpl permissionImpl) async {
    // 申请权限
    Map<Permission, PermissionStatus> permissionMap =
        await  permissions.request();
    for (Permission itemPermission in permissionMap.keys) {
      PermissionStatus status = permissionMap[itemPermission];
      if (null != permissionImpl) {
        permissionImpl.onPermission(
            itemPermission, status == PermissionStatus.granted);
      }
    }
    /*for (PermissionGroup item in permissionMap.keys) {
      PermissionStatus status = permissionMap[item];
      Print.out('$item--$status');
      // 申请结果
      PermissionStatus permission =
          await PermissionHandler().checkPermissionStatus(item);
      if (permission == PermissionStatus.granted) {
        Print.out("权限申请通过");
      } else {
        Print.out("权限申请被拒绝");
      }
    }*/
  }
}

class PreferUtil {
  static Future<bool> set(String key, Object object) async {
    SharedPreferences preferences = await SharedPreferences.getInstance();
    if (object is String)
      return preferences.setString(key, object);
    else if (object is bool)
      return preferences.setBool(key, object);
    else if (object is double)
      return preferences.setDouble(key, object);
    else if (object is int)
      return preferences.setInt(key, object);
    else if (object is List<String>)
      return preferences.setStringList(key, object);
    else
      return true;
  }

  static Future<dynamic> get(String key) async {
    SharedPreferences preferences = await SharedPreferences.getInstance();
    return preferences.get(key);
  }

  static Future<dynamic> getDefault(String key, dynamic defaultValue) async {
    SharedPreferences preferences = await SharedPreferences.getInstance();
    Object obj = preferences.get(key);
    if (ObjUtils.nullable(obj))
      return ObjUtils.nullable(obj) ? defaultValue : obj;
    else
      return obj;
  }

  static void clear() async {
    SharedPreferences preferences = await SharedPreferences.getInstance();
    preferences.clear();
  }
}

class UrlCode {
  static String decode(String s) {
    return TextUtils.isEmpty(s) ? "" : Uri.decodeFull(s);
  }

  static String encode(String s) {
    return TextUtils.isEmpty(s) ? "" : Uri.encodeFull(s);
  }
}

class DatabaseHelper {
  static final DatabaseHelper _instance = DatabaseHelper.internal();

  factory DatabaseHelper() => _instance;

  static Database _db;

  DatabaseHelper.internal();

  Future<Database> get db async {
    _db = await initDb();
    return _db;
  }

  initDb() async {
    String databasesPath = await getDatabasesPath();
    String path = join(databasesPath, TranslateBean.databaseName);
    var db = await openDatabase(path, version: 1, onCreate: _onCreate);
    return db;
  }

  void _onCreate(Database db, int newVersion) async {
    await db.execute('CREATE TABLE ${TranslateBean.tableName}('
        '${TranslateBean.columnDmlb} TEXT NOT NULL, '
        '${TranslateBean.columnDmz} TEXT, '
        '${TranslateBean.columnDmsm} TEXT)');
  }

  Future<int> getCount() async {
    var dbClient = await db;
    int value = Sqflite.firstIntValue(await dbClient
        .rawQuery('SELECT COUNT(*) FROM ${TranslateBean.tableName}'));

    return value;
  }

  Future<TranslateBean> queryItem(String dmlb, String dmz, String dmsm) async {
    var dbClient = await db;
    List<dynamic> whereArgs = List();
    whereArgs.add(dmlb);
    if (!TextUtils.isEmpty(dmz)) {
      whereArgs.add(dmz);
    }
    if (!TextUtils.isEmpty(dmsm)) {
      whereArgs.add(dmsm);
    }
    List<Map> result = await dbClient.query(
      TranslateBean.tableName,
      columns: [
        TranslateBean.columnDmlb,
        TranslateBean.columnDmz,
        TranslateBean.columnDmsm,
      ],
      where: '${TranslateBean.columnDmlb} = ?' +
          (TextUtils.isEmpty(dmz) ? "" : 'AND ${TranslateBean.columnDmz}= ?') +
          (TextUtils.isEmpty(dmsm) ? "" : 'AND ${TranslateBean.columnDmsm}= ?'),
      whereArgs: whereArgs,
    );

    if (result.length > 0) {
      return TranslateBean.fromJson(result.first);
    }

    return null;
  }

  Future<Map<String, dynamic>> queryMapByDmlb(String dmlb) async {
    var dbClient = await db;
    List<dynamic> whereArgs = List();
    whereArgs.add(dmlb);

    List<Map> result = await dbClient.query(
      TranslateBean.tableName,
      columns: [
        TranslateBean.columnDmlb,
        TranslateBean.columnDmz,
        TranslateBean.columnDmsm
      ],
      where: '${TranslateBean.columnDmlb} = ?',
      whereArgs: whereArgs,
    );
    Map<String, dynamic> map = Map();
    if (result.isEmpty) {
      return map;
    }

    result.forEach((_) {
      TranslateBean translateBean = TranslateBean.fromJson(_);
      String key = translateBean.dmz;
      String value = translateBean.dmsm;
      if (map.containsKey(key))
        map.update(key, (_) => value);
      else
        map.putIfAbsent(key, () => value);
    });
    return map;
  }

  Future<String> queryDmsmByDmlbAndDmz(String dmlb, String dmz) async {
    var dbClient = await db;
    List<dynamic> whereArgs = List();
    whereArgs.add(dmlb);
    if (!TextUtils.isEmpty(dmz)) {
      whereArgs.add(dmz);
    }

    List<Map> result = await dbClient.query(
      TranslateBean.tableName,
      columns: [
        TranslateBean.columnDmsm,
      ],
      where: '${TranslateBean.columnDmlb} = ?' +
          (TextUtils.isEmpty(dmz) ? "" : 'AND ${TranslateBean.columnDmz}= ?'),
      whereArgs: whereArgs,
    );

    if (result.length > 0) {
      return TranslateBean.fromJson(result.first).dmsm;
    }

    return null;
  }

  Future<String> queryDmzByDmlbAndDmsm(String dmlb, String dmsm) async {
    var dbClient = await db;
    List<dynamic> whereArgs = List();
    whereArgs.add(dmlb);
    if (!TextUtils.isEmpty(dmsm)) {
      whereArgs.add(dmsm);
    }

    List<Map> result = await dbClient.query(
      TranslateBean.tableName,
      columns: [
        TranslateBean.columnDmz,
      ],
      where: '${TranslateBean.columnDmlb} = ?' +
          (TextUtils.isEmpty(dmsm) ? "" : 'AND ${TranslateBean.columnDmsm}= ?'),
      whereArgs: whereArgs,
    );

    if (result.length > 0) {
      return TranslateBean.fromJson(result.first).dmz;
    }

    return null;
  }

  Future<List> queryBeanList({int limit, int offset}) async {
    var dbClient = await db;
    var result = await dbClient.query(
      TranslateBean.tableName,
      columns: [
        TranslateBean.columnDmlb,
        TranslateBean.columnDmz,
        TranslateBean.columnDmsm
      ],
      limit: limit,
      offset: offset,
    );

    return result.toList();
  }

  ///
  Future<TranslateBean> queryItemByBean(TranslateBean translateBean) async {
    if (null == translateBean) return null;
    String dmlb = translateBean.dmlb;
    String dmz = translateBean.dmz;
    var dbClient = await db;
    String where = '${TranslateBean.columnDmlb} = ? ' +
        (TextUtils.isEmpty(dmz) ? '' : 'AND ${TranslateBean.columnDmz} = ?');
    List<dynamic> whereArgs = List();
    whereArgs.add(dmlb);
    if (!TextUtils.isEmpty(dmz)) {
      whereArgs.add(dmz);
    }
    List<Map> result = await dbClient.query(
      TranslateBean.tableName,
      columns: [
        TranslateBean.columnDmlb,
        TranslateBean.columnDmz,
        TranslateBean.columnDmsm,
      ],
      where: where,
      whereArgs: whereArgs,
    );

    if (result.length > 0) {
      return TranslateBean.fromJson(result.first);
    }
    return null;
  }

  Future<Map<String, TranslateBean>> queryMapByList(
      List<TranslateBean> beanList) async {
    Map<String, TranslateBean> map = {};
    if (null == beanList || beanList.isEmpty) return map;
    for (TranslateBean item in beanList) {
      TranslateBean translateBean = await queryItemByBean(item);
      map.putIfAbsent(item.dmlb, () => translateBean);
    }
    return map;
  }

  Future<Map<String, List<Map>>> queryMapListByList(
      List<TranslateBean> beanList) async {
    Map<String, List<Map>> map = {};
    if (null == beanList || beanList.isEmpty) return map;
    for (TranslateBean item in beanList) {
      item.dmsm = '';
      item.dmz = '';
      List<Map> _beanList = await queryListByBean(item);
      map.putIfAbsent(item.dmlb, () => _beanList);
    }
    return map;
  }

  Future<Map<String, Map<String, dynamic>>> queryMapByDmlbList(
      List<TranslateBean> beanList) async {
    Map<String, Map<String, dynamic>> map = {};
    if (null == beanList || beanList.isEmpty) return map;
    for (TranslateBean item in beanList) {
      Map<String, dynamic> _tmpMap = await queryMapByDmlb(item.dmlb);
      map.putIfAbsent(item.dmlb, () => _tmpMap);
    }
    return map;
  }

  Future<List<Map>> queryListByBean(TranslateBean translateBean) async {
    if (null == translateBean) return null;
    String dmlb = translateBean.dmlb;
    var dbClient = await db;
    String where = '${TranslateBean.columnDmlb} = ?';
    List<Map> result = await dbClient.query(
      TranslateBean.tableName,
      columns: [
        TranslateBean.columnDmlb,
        TranslateBean.columnDmz,
        TranslateBean.columnDmsm,
      ],
      where: where,
      whereArgs: [dmlb],
    );
    return result;
  }

  Future<int> saveItem(TranslateBean translateBean) async {
    return saveBeanList([translateBean]);
  }

  Future<int> saveBeanList(List<TranslateBean> beanList) async {
    var dbClient = await db;
    var batch = dbClient.batch();
    beanList.forEach((bean) {
      batch.insert(TranslateBean.tableName, TranslateBean.bean2Json(bean));
    });
    //返回每个数据库操作的结果组成的数组 [6, 3, 0]：新增返回id=6，修改了3条数据，删除了0条数据
    var results = await batch.commit();

    return results.length;
  }

  Future<int> updateItem(TranslateBean translateBean) async {
    return updateList([translateBean]);
  }

  Future<int> updateList(List<TranslateBean> beanList) async {
    var dbClient = await db;
    var batch = dbClient.batch();
    for (TranslateBean item in beanList) {
      TranslateBean translateBean = await queryItemByBean(item);
      if (null != translateBean) {
        batch.update(TranslateBean.tableName, TranslateBean.bean2Json(item),
            where: '${TranslateBean.columnDmlb}= ? ', whereArgs: [item.dmlb]);
      }
    }
    var results = await batch.commit();
    return results.length;
  }

  Future<int> insertOrReplace(TranslateBean translateBean) async {
    return insertOrReplaceList([translateBean]);
  }

  Future<int> insertOrReplaceList(List<TranslateBean> beanList) async {
    var dbClient = await db;
    var batch = dbClient.batch();
    for (TranslateBean item in beanList) {
      String dmlb = item.dmlb;
      String dmz = item.dmz;
      String dmsm = item.dmsm;

      if (TextUtils.isEmpty(dmlb) ||
          TextUtils.isEmpty(dmz) ||
          TextUtils.isEmpty(dmsm)) {
        continue;
      }
      TranslateBean translateBean = await queryItemByBean(item);

      if (null == translateBean) {
        batch.insert(TranslateBean.tableName, TranslateBean.bean2Json(item));
      } else {
        List<dynamic> whereArgs = List();
        whereArgs.add(dmlb);
        if (!TextUtils.isEmpty(dmz)) {
          whereArgs.add(dmz);
        }
        if (!TextUtils.isEmpty(dmsm)) {
          whereArgs.add(dmsm);
        }
        String where = '${TranslateBean.columnDmlb}= ? ' +
            (TextUtils.isEmpty(dmz)
                ? ""
                : 'AND ${TranslateBean.columnDmz}= ?') +
            (TextUtils.isEmpty(dmsm)
                ? ""
                : 'AND ${TranslateBean.columnDmsm}= ?');

        batch.update(TranslateBean.tableName, TranslateBean.bean2Json(item),
            where: where, whereArgs: whereArgs);
      }
    }
    var results = await batch.commit();

    return results.length;
  }

  Future<int> deleteItem(String dmlb) async {
    var dbClient = await db;
    int count = await dbClient.delete(TranslateBean.tableName,
        where: '${TranslateBean.columnDmlb}= ?', whereArgs: [dmlb]);

    return count;
  }

  Future<int> deleteAll() async {
    if (await getCount() == 0) {
      return 0;
    }
    var dbClient = await db;
    int count = await dbClient.delete('${TranslateBean.tableName}');

    return count;
  }

  Future close() async {
    var dbClient = await db;
    if (null != dbClient && dbClient.isOpen) dbClient.close();
  }
}

class GsonUtil {
  static String bean2Json(Object obj) {
    if (null == obj) return "{}";
    return json.encode(obj);
  }

  static String list2Json(List obj) {
    if (null == obj) return "[]";
    return json.encode(obj);
  }

  static Map<String, dynamic> list2Map(List list) {
    if (null == list) return {};
    return json.decode(json.encode(list));
  }
}

class TimeUtil {
  static String subTime(String time) {
    if (TextUtils.isEmpty(time)) return "";
    return time
        .toLowerCase()
        .replaceAll('+', '')
        .replaceAll('00:00:00', '')
        .replaceAll('.0', '')
        .trim();
  }
}

class Log {
  static bool debug = true;

  static void out(Object object, {String tag}) {
    if (debug == true) print(TextUtils.isEmpty(tag) ? object : '$tag##$object');
  }
}

///#FileUtil
///带Sync表示同步方法
///否则是异步
///open和openSync一样，不过一个是异步、一个同步
class FileUtil {
  static Future<String> getInstance() async {
    Directory parentDir = await getApplicationDocumentsDirectory();
    String path = parentDir.path;
    return path;
  }

  static Future<Directory> createDir(String dirName) async {
    String dirPath = await getInstance();
    Directory parentDir =
        await Directory('$dirPath${Platform.pathSeparator}$dirName')
            .create(recursive: true);
    return parentDir;
  }

  static Future<File> writeAsString(String filePath, String content) async {
    String dirPath = await getInstance();
    File file = File('$dirPath/$filePath');
    Future<bool> exists = file.exists();
    if (!await exists) {
      file.create(recursive: true);
    }
    file = await file.writeAsString(content, flush: true);
    return file;
  }

  static Future<File> writeAsBytes(String filePath, Uint8List uint8list) async {
    String dirPath = await getInstance();
    File file = File('$dirPath/$filePath');
    Future<bool> exists = file.exists();
    if (!await exists) {
      file.create(recursive: true);
    }
    file = await file.writeAsBytes(uint8list, flush: true);
    return file;
  }

  static Future<List<FileSystemEntity>> listSync(String dirPath) async {
    List<FileSystemEntity> entityList = List();
    Directory directory = await createDir(dirPath);
    bool exists = await directory.exists();
    if (exists) {
      entityList = directory.listSync(followLinks: false, recursive: true);
    }
    return entityList;
  }

  ///异步删除文件夹
  /// [recursive]是否递归
  static Future<FileSystemEntity> deleteDirs(Directory directory,
      {bool recursive = true}) async {
    return await directory.delete(recursive: recursive);
  }

  static void deleteDirsSync(Directory directory) {
    return directory.deleteSync(recursive: true);
  }

  static Future<FileSystemEntity> deleteFile(File file) async {
    Log.out('${file.path}', tag: '删除文件');

    return file.delete(recursive: true);
  }

  static void deleteDirsWithChild({String dirPath}) async {
    var type = await FileSystemEntity.type(dirPath);
    //Log.out('$type', tag: '文件类型');

    bool filePath = await FileSystemEntity.isFile(dirPath);
    //Log.out('$filePath', tag: '是文件路径');
    if (filePath) {
      File file = File(dirPath);
      if (await file.exists()) {
        //Log.out('${file.path}', tag: '文件存在');
        await deleteFile(file);
      }
      return;
    }

    Directory directory = await createDir(dirPath);
    bool exists = await directory.exists();
    if (exists) {
      //Log.out('${directory.path}', tag: '文件夹存在');
      //var dirDelete = await directory.delete(recursive: true);
      await deleteDirs(directory);
      //bool deEx =await dirDelete.exists();
      //Log.out('$deEx', tag: '文件夹删除后是否存在');
      //Log.out('${dirDelete.path}', tag: '文件夹删除后的路径');
      //Log.out('${dirDelete.parent.path}', tag: '文件夹删除后的父路径');

      /*List<FileSystemEntity> listFile =
      directory.listSync(followLinks: false, recursive: true);
      if (listFile.isEmpty) {
        Log.out('${directory.path}', tag: '空文件夹');
        var dirDelete = await directory.delete(recursive: true);
        bool deEx = await dirDelete.exists();
        Log.out('$deEx', tag: '删除之后是否存在');
        Log.out('${dirDelete.parent.path}', tag: '删除之后的路径');
      } else {
        listFile.forEach((_) async* {
          Log.out('${_.path}', tag: '删除文件夹的每一项');
          deleteDirsWithChild(dirPath: _.path);
        });
        var dirDelete = await directory.delete(recursive: true);
        bool deEx = await dirDelete.exists();
        Log.out('$deEx', tag: '子项删除之后是否存在');
        Log.out('${dirDelete.parent.path}', tag: '子项删除之后的路径');
      }*/
    }
  }
}

class ListUtil {
  static List<DropdownMenuItem<String>> defaultDropList({String text = '请选择'}) {
    List<DropdownMenuItem<String>> _defaultList = List();
    DropdownMenuItem _dropdownMenuItem = DropdownMenuItem<String>(
      child: Text('$text'),
      value: '',
    );
    _defaultList.add(_dropdownMenuItem);
    return _defaultList;
  }

  static List<String> defaultList({String text = '请选择'}) {
    List<String> _defaultList = List();
    _defaultList.add('$text');
    return _defaultList;
  }

  static List<DropdownMenuItem<String>> json2DropList(
      String result, String key1, String key2) {
    if (TextUtils.isEmpty(result)) {
      return List();
    }
    List array = json.decode(result);
    return array
        .map((map) => DropdownMenuItem<String>(
              child: Text('${map[key1]}'),
              value: '${map[key2]}',
            ))
        .toList();
  }

  static List<DropdownMenuItem<String>> list2DropList(List list,
      {bool defaultValue = false, String text = ''}) {
    List<DropdownMenuItem<String>> dropList = List();

    List<DropdownMenuItem<String>> defaultList = defaultDropList(text: text);
    if (null == list || list.isEmpty) {
      if (defaultValue) {
        dropList.addAll(defaultList);
      }
      return dropList;
    }
    List<DropdownMenuItem<String>> transList = list.map((map) {
      return DropdownMenuItem<String>(
        child: Text('${map['dmsm']}'),
        value: '${map['dmz']}',
      );
    }).toList();
    if (defaultValue) {
      dropList.addAll(defaultList);
    }
    dropList.addAll(transList);
    return dropList;
  }
}
